package com.example.lib_skin;

import android.annotation.SuppressLint;
import android.app.Application;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;

import androidx.core.content.ContextCompat;

import java.lang.reflect.Method;

/**
 * @ClassName: SkinResource
 * @Author: 史大拿
 * @CreateDate: 1/3/23$ 9:45 AM$
 * TODO 资源具体实现
 */
public class SkinResource {

    private volatile static SkinResource mInstance;
    private final Application mApplication;

    private Resources mResource;
    // apk资源
    public String mPath;

    private SkinResource(Application application, String path) {
        mApplication = application;
        this.mPath = path;
        this.mResource = createSkinResource(mPath);
    }

    public static void init(Application application, String path) {
        if (mInstance == null) {
            synchronized (SkinResource.class) {
                if (mInstance == null)
                    mInstance = new SkinResource(application, path);
            }
        }
    }


    public static SkinResource getInstance() {
        if (mInstance == null) {
            throw new RuntimeException("SkinResource没有初始化;" + SkinConfig.SKIN_ERROR_5);
        }
        return mInstance;
    }

    /*
     * 作者:史大拿
     * 创建时间: 1/4/23 10:27 AM
     * TODO 恢复皮肤包状态
     */
    public void resume() {
        if (isResume()) {
            mResource = createSkinResource(mPath);
        }
    }

    /*
     * 作者:史大拿
     * 创建时间: 1/4/23 10:27 AM
     * TODO 是否需要恢复皮肤包
     */
    public boolean isResume() {
        return mResource == mApplication.getResources();
    }

    /*
     * 作者:史大拿
     * 创建时间: 1/4/23 10:27 AM
     * TODO 重制
     */
    public void reset() {
        // 将皮肤包的资源指向system资源
        mResource = mApplication.getResources();
    }

    /*
     * 作者:史大拿
     * 创建时间: 1/3/23 9:51 AM
     * TODO 创建皮肤包中的资源
     * @param path: 皮肤包在手机中的路径
     */
    private Resources createSkinResource(String path) {
        try {
            AssetManager assetManager = AssetManager.class.newInstance();

            String addAssetPath = "addAssetPath";

            @SuppressLint("DiscouragedPrivateApi")
            Method method = AssetManager.class.getDeclaredMethod(addAssetPath, String.class);
            method.setAccessible(true);
            /// 反射执行方法
            method.invoke(assetManager, path);
            return new Resources(assetManager, createDisplayMetrics(), createConfiguration());
        } catch (Exception e) {
            throw new RuntimeException("Resources创建失败;" + SkinConfig.SKIN_ERROR_4);
        }
    }

    public DisplayMetrics createDisplayMetrics() {
        return mApplication.getResources().getDisplayMetrics();
    }

    public Configuration createConfiguration() {
        return mApplication.getResources().getConfiguration();
    }

    /*
     * 作者:史大拿
     * 创建时间: 1/3/23 5:13 PM
     * TODO 重载, 如果重载表示获取当前apk包名
     */
    private String getPackName() {
        return getPackName(null);
    }

    /*
     * 作者:史大拿
     * 创建时间: 1/3/23 2:33 PM
     * TODO 获取包名
     */
    public String getPackName(String path) {
        if (path != null && !path.isEmpty()) {
            PackageInfo info = mApplication.getPackageManager().getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
            if (info != null) {
                ApplicationInfo appInfo = info.applicationInfo;
                return appInfo.packageName;  //得到安装包名称
            }
        }

        return mApplication.getPackageName();
    }

    public int getColor(String value) {
        SkinLog.i("szjColorValue:", value);
        // 先获取皮肤包中的id
        int id = mResource.getIdentifier(value, "color", getPackName(mPath));

        // id == 0 表示皮肤包中没有该资源
        if (id == 0) {

            // 再次获取本地的资源
            id = getSystemResourceId(value, "color");

            // 如果本地资源没有获取到，尝试吧这个参数当作系统资源再次获取
            if (id == 0)
                id = getSystemResourceId("android:" + value, "color");


            // 本地资源存在
            if (id != 0) {
                return ContextCompat.getColor(mApplication, id);
            }


            // 本地资源也不存在就throw异常
            throwRuntimeException("color");
        }

        // 皮肤包资源存在，直接返回
        return mResource.getColor(id, null);
    }


    // 和 getColor() 同理，这里注释就不加了
    public String getString(String value) {
        int id = mResource.getIdentifier(value, "string", getPackName(mPath));
        if (id == 0) {
            id = getSystemResourceId(value, "string");

            if (id == 0)
                id = getSystemResourceId("android:" + value, "string");

            if (id != 0) {
                return mApplication.getString(id);
            }

            throwRuntimeException("string");
        }
        return mResource.getString(id);
    }

    public Drawable getDrawable(String value) {
        int id = mResource.getIdentifier(value, "drawable", getPackName(mPath));
        if (id == 0) {
            id = getSystemResourceId(value, "drawable");

            if (id == 0)
                id = getSystemResourceId("android:" + value, "drawable");

            if (id != 0) {
                return ContextCompat.getDrawable(mApplication, id);
            }
            throwRuntimeException("Drawable");
        }
        return mResource.getDrawable(id, null);
    }


    public float getFontSize(String value) {
        int id = mResource.getIdentifier(value, "dimen", getPackName(mPath));
        if (id == 0) {
            id = getSystemResourceId(value, "dimen");

            if (id == 0)
                id = getSystemResourceId("android:" + value, "dimen");

            if (id != 0) {
                return mApplication.getResources().getDimension(id);
            }

            throwRuntimeException("dimen");
        }
        return mResource.getDimension(id);
    }

    /*
     * 作者:史大拿
     * 创建时间: 1/4/23 10:23 AM
     * TODO 获取系统资源id
     */
    private int getSystemResourceId(String value, String defType) {
        return mApplication.getResources().getIdentifier(value, defType, getPackName());
    }


    private void throwRuntimeException(String type) {
        throw new RuntimeException("皮肤包和本地资源都没有当前属性(" + type + ");" + SkinConfig.SKIN_ERROR_6);
    }
}
